/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ajustecurvas.controller;

import ajustecurvas.Ponto;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Luan Carlos, Anderson Rocha, Jadson Francisco
 */
public class RacionalAjusteController extends AjusteController{
    String equacao = "";
    double pearson;
    double[] ab;
    double n;
    List<Ponto> listaPontos;
    
    @Override
    public List<Ponto> calcular(List<Ponto> medidas) {
       
        n = medidas.size();
        double[] xi = parametrosXeY(medidas, 0);   
        double[] yi = parametrosXeY(medidas, 1);
        
        double[] zi = inverterYi(yi); // zi = 1/yi;
        double somaX = soma(xi);
        double somaY = soma(zi);
        double somaXY = somaXY(xi,zi);
        double somaXX = soma2(xi);
        double somaYY = soma2(yi);
        
        System.out.println("Soma xi: " + somaX);
        System.out.println("Soma yi: " + somaY);
      
        System.out.println("Soma xiYi: " + somaXY);
        System.out.println("Soma xi2: " + somaXX);
        System.out.println("Soma Yi2: " + somaYY);

        
        ab = calcularAB(n,somaX, somaY,somaXY, somaXX);
        
        
        double[] yipost = parametrosYpost(xi);
        double somaYYpost = soma2(yipost);
        double somaXYpost = somaXY(xi, yipost);
        double somaYpost = soma(yipost);
        
        double numeradorPearson = calcularNumeradorPearson(xi,yi);
        double denominadorPearson = calcularDenominadorPearson(yi);
         
        
     //  pearson = calcularQualidade(numeradorPearson, denominadorPearson);
          pearson = calcQualidade(somaX, somaY, somaXY, somaXX, somaYY);
        
        listaPontos = gerarPontos(xi);
        
        return listaPontos;
    }
    
    
    private double[] parametrosXeY(List<Ponto> medidas, int j) {
        double[] valores = new double[medidas.size()];

        for (int i = 0; i < valores.length; i++) {
            if (j == 0) {
                valores[i] = medidas.get(i).getX();
            } else {
                valores[i] = medidas.get(i).getY();
            }
        }

        return valores;
    }
    
    private double[] inverterYi(double[] y1){
        double[] valores = new double[y1.length];
        
        for(int i=0;i<valores.length;i++){
            valores[i] = (1/y1[i]);
    
        }
        
        return valores;
    }
    
    private double soma(double[] x){
        double soma = 0;
        for(int i=0;i<x.length;i++){
            soma += x[i];
        }
        
        return soma;
    }
    
    private double somaXY(double[] x, double[] y){
        double soma = 0;
        
        for(int i=0;i<x.length;i++){
            soma += x[i]*y[i];
        }
        
        return soma;
    }
    
    private double[] parametrosYpost(double[] x){
        double y[] = new double[x.length];
        
        for(int i=0;i<x.length;i++){
            y[i] = funcaoRacional(x[i]);
             
        }
        
        return y;
    }
    
    private double soma2(double[] x){
        double soma = 0;
        
        for(int i=0;i<x.length;i++){
            soma += Math.pow(x[i], 2);
        }
        
        return soma;
    } 
    private double[] calcularAB(double n,double somaX, double somaY,double somaXY, double somaXX){
        double[] ab = new double[2];
        /*double de = (n * somaXY) - (somaX * somaY);
        double di = (n * somaXX) - (Math.pow(somaX, 2));
        double a = (de / di);
        double deb = somaY - (a*somaX);
        double b = (deb/n);*/
        double num = (somaXY*n) - (somaX*somaY);
        double den = (somaXX*n)-(Math.pow(somaX, 2));
        
        double b = (num/den);
        double a = ((somaY-(b*somaX))/n);
        
        
        ab[0] = a;
        ab[1] = b;
        
        
        
        return ab;
    }
    
    private List<Ponto> gerarPontos(double[] x){
         ArrayList<Ponto> lista = new ArrayList<Ponto>();
         double y;
         
         for(int i =0;i<x.length;i++){
            y =  funcaoRacional(x[i]);
            
            Ponto p = new Ponto(x[i], y);
            lista.add(p);
         }
         
         return lista;
    }
    
    private double funcaoRacional(double x){
        return (1/(ab[0] + (ab[1]*x)));
    }
    
    private double calcularNumeradorPearson(double[] x, double[] y){
        double numerador = 0;
        for(int i =0;i<n;i++){
            numerador += Math.pow((y[i] - funcaoRacional(x[i])), 2);
        }
        
        return n*numerador;
        
    }
    
    private double calcularDenominadorPearson(double[] y){
        double denominador = 0;
        double d1 = 0;
        double d2 = 0;
        
        for(int i=0;i<n;i++){
            d1 += Math.pow(y[i], 2);
        }
        
        d1 = d1*n;
        
        
        for(int i=0;i<n;i++){
            d2 += y[i];
        }
        
        d2 = Math.pow(d2, 2);
        
        denominador = d1-d2;
        
        return denominador;
        
        
    }
    
    private double calcularQualidade(double numerador,double denominador){
        double var = 1-(numerador/denominador);
        System.out.println("var= " + var);

        return var;
    }
    
    private double calcQualidade(double somaX, double somaY, double somaXY, double somaXX, double somaYY){
        double numerador = 0;
        double denominador = 0;
        double d1 = 0;
        double d2 = 0;
        
          numerador = ((n*somaXY)-(somaX*somaY));
        d1 = ((n*somaXX)- (Math.pow(somaX, 2)));
        d2 = ((n*somaYY)- (Math.pow(somaY, 2)));
        denominador = d1*d2;
        denominador = Math.sqrt(denominador);
        
        return (numerador/denominador);
        
      
        
    }
    

    @Override
    public String getEquacao() {
        DecimalFormat df = new DecimalFormat("0.00");
        String A = df.format(ab[0]);
        String B = df.format(ab[1]);
        equacao = "1/(" + A + " " + B +"*x)";
        
        return equacao;
    }

    @Override
    public double getQualidade() {
       return pearson;
    }
    
}
